﻿namespace EyeOpen.Security
{
	using System;
	using System.Linq;
	using System.Security;
	using System.Web.Security;
	using EyeOpen.Data;
	using EyeOpen.Domain;

	public class WebSiteMembershipProvider : MembershipProviderBase
	{
		/// <exception cref="ArgumentException">Username and email must be identical.</exception>
		public override MembershipUser CreateUser(string username, string password, string email, string passwordQuestion, string passwordAnswer, bool isApproved, object providerUserKey, out MembershipCreateStatus status)
		{
			if (!username.Equals(email, StringComparison.InvariantCultureIgnoreCase))
			{
				throw new ArgumentException("Username and email must be identical.");
			}

			if (passwordAnswer != null)
			{
				throw new ArgumentException("Password retrieve is not supported.");
			}

			if (passwordQuestion != null)
			{
				throw new ArgumentException("Password retrieve is not supported.");
			}

			var user = new User { Id = Guid.NewGuid(), Email = email, Password = User.CreatePassword(password) };

			using (var dbContext = new WebSiteDbContext("WebSiteConnection"))
			{
				dbContext
					.UserRepository
					.Add(user);
			}

			status = MembershipCreateStatus.Success;

			var now = DateTime.Now;

			return new MembershipUser(
				GetType().Name,
				user.Email,
				user.Id,
				user.Email,
				null,
				null,
				false,
				true,
				now,
				now,
				now,
				now,
				now);
		}

		/// <exception cref="SecurityException">Old password is not correct.</exception>
		public override bool ChangePassword(string username, string oldPassword, string newPassword)
		{
			using (var dbContext = new WebSiteDbContext("WebSiteConnection"))
			{
				var user =
					dbContext
						.UserRepository
						.Single(u => u.Email == username);

				if (user.Password != User.CreatePassword(oldPassword))
				{
					throw new SecurityException("Old password is not correct.");
				}

				user.Password = User.CreatePassword(newPassword);

				dbContext.SaveChanges();
			}

			return true;
		}

		public override bool ValidateUser(string username, string password)
		{
			using (var dbContext = CreateUow())
			{
				var user =
					dbContext
						.UserRepository
						.SingleOrDefault(u => u.Email == username);

				return 
					user != null && 
					user.Password.SequenceEqual(User.CreatePassword(password));
			}
		}

		private WebSiteDbContext CreateUow()
		{
			return new WebSiteDbContext("WebSiteConnection");
		}
	}
}